package misc;

import java.lang.reflect.Array;

public class MArrayList<E> {
	private E[] elements;

	/**
	 * @param c
	 *           Class type of the elements that the array should contain.
	 * @param size
	 *           Size of the array.
	 * @return A new (resized) generic array with generic elements.
	 */
	@SuppressWarnings("unchecked")
	public E[] create(Class<E> c, int size) {
		return (E[]) Array.newInstance(c, size);
	}

	@SuppressWarnings("unchecked")
	public void add(E e) {
		// if the array is null, create a new array of Class e, and add e to the array and return
		if (elements == null) {
			elements = create((Class<E>) e.getClass(), 1);
			elements[0] = e;
			return;
		}
		// if the array already contains e, return
		if (contains(e))
			return;
		// resize the array by creating a new array with new size
		E[] newElements = create((Class<E>) e.getClass(), elements.length + 1);
		// copy all elements
		for (int i = 0; i < elements.length; i++) {
			newElements[i] = elements[i];
		}
		// add the new element to the last position
		newElements[newElements.length - 1] = e;
		// replace the old array with the new
		elements = newElements;
	}

	@SuppressWarnings("unchecked")
	public void remove(E e) {
		// if the array doesn't contain the element e, return
		if (!contains(e))
			return;
		// resize the array by creating a new array with new size
		E[] newElements = create((Class<E>) e.getClass(), elements.length - 1);
		int c = 0;
		// copy all elements, except the to be removed element e
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] != e)
				newElements[c++] = elements[i];
		}
		// replace the old array with the new
		elements = newElements;
	}

	public boolean contains(E e) {
		if (elements == null)
			return false;
		if (elements.length == 0)
			return false;
		// if the array contains the element e, return true
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] == e)
				return true;
		}
		return false;
	}

	public E getFirst() {
		if (elements == null)
			return null;
		return elements[0];
	}

	public E getLast() {
		if (elements == null)
			return null;
		return elements[elements.length - 1];
	}

	public E[] getArray() {
		return elements;
	}

	public E get(E element) {
		for (int i = 0; i < elements.length; i++) {
			if (elements[i] == element)
				return element;
		}
		return null;
	}

	public int size() {
		if (elements == null)
			return 0;
		return elements.length;
	}

	public boolean isEmpty() {
		if (elements == null)
			return true;
		return size() == 0;
	}

	public void clear() {
		elements = null;
	}
}
